package io.admin.modules.sys.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.admin.common.page.PageData;
import io.admin.common.service.impl.CrudServiceImpl;
import io.admin.common.utils.BaiduMapImageExporter;
import io.admin.common.utils.ConvertUtils;
import io.admin.common.utils.DateUtil;
import io.admin.common.utils.DocxMerge;
import io.admin.common.utils.ExcelUtils;
import io.admin.common.utils.StringUtils;
import io.admin.modules.sys.dao.LineDao;
import io.admin.modules.sys.dao.ProjectDao;
import io.admin.modules.sys.dto.EquipmentDTO;
import io.admin.modules.sys.dto.FileUrlDTO;
import io.admin.modules.sys.dto.LineDTO;
import io.admin.modules.sys.dto.SysDictDataDTO;
import io.admin.modules.sys.dto.SysDictTypeDTO;
import io.admin.modules.sys.entity.BaiduMapImgEntity;
import io.admin.modules.sys.entity.EquipmentEntity;
import io.admin.modules.sys.entity.EquipmentEntityPage;
import io.admin.modules.sys.entity.FileUrlEntity;
import io.admin.modules.sys.entity.LineEntity;
import io.admin.modules.sys.entity.LineEntityPage;
import io.admin.modules.sys.entity.SelectEntity;
import io.admin.modules.sys.service.EquipmentService;
import io.admin.modules.sys.service.FileUrlService;
import io.admin.modules.sys.service.LineService;
import io.admin.modules.sys.service.SysDictDataService;
import io.admin.modules.sys.service.SysDictTypeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 项目线路关系表
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2024-07-06
 */
@Slf4j
@Service
public class LineServiceImpl extends CrudServiceImpl<LineDao, LineEntity, LineDTO> implements LineService {

    @Autowired
    private LineDao lineDao;

    @Autowired
    private ProjectDao projectDao;

    @Autowired
    private EquipmentService equipmentService;
    @Autowired
    private FileUrlService fileUrlService;
    @Autowired
    private  SysDictDataService sysDictDataService;
    @Autowired
    private    SysDictTypeService sysDictTypeService;
    private final  static String ADDRESS_FILE = ExcelUtils.ADDRESS_FILE;


    @Override
    public PageData page(Map<String, Object> params) {
        //转换成like
        paramsToLike(params, "name");
        //分页
        IPage<LineEntity> page = getPage(params, "", false);
        //查询
        List<LineEntityPage> list = lineDao.getList(params);
        if (!CollectionUtil.isEmpty(list)) {
            for (LineEntityPage p : list) {
                p.setEquipmentNum(equipmentService.getLineCount(p.getId(), null));
            }
        }
        return new PageData(list, page.getTotal());
    }

    @Override
    public QueryWrapper<LineEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");
        String projectId = (String) params.get("projectId");
        QueryWrapper<LineEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
        wrapper.eq(StrUtil.isNotBlank(projectId), "project_id", projectId);
        return wrapper;
    }

    @Override
    public List<SelectEntity> findProSelect() {
        return projectDao.findProSelect();
    }

    @Override
    public List<SelectEntity> findLineSelect(String proId) {
        return lineDao.findLineSelect(proId);
    }

    @Override
    public void saveCopyLine(String lineId, String thisProjectId) {
        //开始查询当前线路信息
        Long copyLineId = generateRandomLongId();
        LineEntity lineEntity = baseDao.selectById(lineId);
        if (null == lineEntity) {
            return;
        }
        //开始获取所有的 定点信息
        Map<String, Object> param = new HashMap<String, Object>(1);
        param.put("lineId", String.valueOf(lineEntity.getId()));
        List<EquipmentDTO> listEquipment = equipmentService.list(param);
        if (CollectionUtil.isEmpty(listEquipment)) {
            //修改用线路的项目id
            lineEntity.setId(copyLineId);
            lineEntity.setProjectId(Long.valueOf(thisProjectId));
            baseDao.insert(lineEntity);
            return;
        }
        List<FileUrlDTO> listFile = new ArrayList<>();
        //开始获取所有的 定点图片信息
        for (EquipmentDTO equipmentDTO : listEquipment) {
            param = new HashMap<String, Object>(1);
            param.put("keysId", String.valueOf(equipmentDTO.getId()));
            Long equiId = generateRandomLongId();
            List<FileUrlDTO> listFileUrl = fileUrlService.list(param);
            if (!CollectionUtil.isEmpty(listFileUrl)) {
                for (FileUrlDTO fileUrlDTO : listFileUrl) {
                    fileUrlDTO.setId(generateRandomLongId());
                    fileUrlDTO.setKeysId(equiId);
                }
                listFile.addAll(listFileUrl);
            }
            equipmentDTO.setId(equiId);
            equipmentDTO.setLineId(copyLineId);
            equipmentDTO.setProjectId(Long.valueOf(thisProjectId));
        }
        log.info("新增线路");
        lineEntity.setId(copyLineId);
        lineEntity.setProjectId(Long.valueOf(thisProjectId));
        baseDao.insert(lineEntity);
        log.info("开始新增定点信息");
        List<EquipmentEntity> listEquipmentEntity = ConvertUtils.sourceToTarget(listEquipment, EquipmentEntity.class);
        equipmentService.insertBatch(listEquipmentEntity);
        log.info("开始新增图片信息");
        if (!CollectionUtil.isEmpty(listFile)) {
            List<FileUrlEntity> listFileUrlEntity = ConvertUtils.sourceToTarget(listFile, FileUrlEntity.class);
            fileUrlService.insertBatch(listFileUrlEntity);
        }
    }

    public LineDTO findLineByParam(LineDTO lineDTO) {
        return lineDao.findLineByParam(lineDTO);
    }

    public String exportByLineId(String lineIds,String zoom,String imgName,Map<String,Object> excel) {
        String fileName =DateUtil.currentTimestamp().getTime()+".docx";
        //开始获取所有的 线路数据
        if(StringUtils.isBlank(lineIds)){
            return null;
        }
        List<File> list = new ArrayList<>();
        try {
            String[] lineIdArray = lineIds.split(",");
            for (String lineId:lineIdArray){
                LineEntity lineData = baseDao.selectById(Long.valueOf(lineId));
                if (null == lineData) {
                    return null;
                }
                Map<String, Object> param = new HashMap<>();
                param.put("lineId", lineId);
                param.put("projectId", lineData.getProjectId());
                List<EquipmentEntityPage> eqList = equipmentService.getLineList(param);
                //String imgFileName = dataImg(eqList,zoom);
                String fileNameWord = exporterWord(lineData,eqList,imgName,excel);
                if(StringUtils.isNotBlank(fileNameWord)){
                    File file =new File(ADDRESS_FILE+fileNameWord);
                    list.add(file);
                }
            }
            //开始合并word
            if(list.size()>0){
                DocxMerge.appendDocx(new File(ADDRESS_FILE+fileName), list);
                return fileName;
            }else{
                return null;
            }
        }catch ( Exception e){
            e.printStackTrace();
            log.info(e.getMessage());
            return null;
        }finally {
            if(list.size()>0){
                for (File file:list){
                    if(file.exists()){
                        file.delete();
                    }
                }
            }
        }

    }

    public String dataImg(List<EquipmentEntityPage> eqList,String zoom) {
        //开始获取地图
        if (CollectionUtil.isEmpty(eqList)) {
            return null;
        }
        List<BaiduMapImgEntity> baiduMapImgEntityList = new ArrayList<>();
        for (EquipmentEntityPage data : eqList) {
            BaiduMapImgEntity baiduMapImgEntity = new BaiduMapImgEntity();
            baiduMapImgEntity.setIcon(StringUtils.isBlank(
                    data.getEquipmentTypeMinUrl())
                    ?data.getEquipmentTypeUrl()
                    :data.getEquipmentTypeMinUrl()
            );
            baiduMapImgEntity.setLgt(data.getLgt());
            baiduMapImgEntity.setDms(data.getDms());
            baiduMapImgEntity.setName(data.getName());
            baiduMapImgEntityList.add(baiduMapImgEntity);
        }
        if(StringUtils.isBlank(zoom)){
            zoom ="19";
        }
        int middleIndex = 0;
        if( baiduMapImgEntityList.size()>2){
            Object index =getMiddleElement(baiduMapImgEntityList);
            middleIndex = Integer.parseInt(index.toString());
        }
        log.info("总标点数"+baiduMapImgEntityList.size()+"选中的标点"+middleIndex);
        BaiduMapImgEntity baiduMapImgEntity = baiduMapImgEntityList.get(middleIndex);
        String fileName = DateUtil.currentTimestamp().getTime() + "_baidu.jpg";
        try {
            BaiduMapImageExporter.exportBaiduMapImage(
                    baiduMapImgEntity.getLgt(),
                    baiduMapImgEntity.getDms(),
                    Integer.valueOf(zoom),
                    1000, 900, fileName, baiduMapImgEntityList
            );
        } catch (Exception e) {
           log.info(e.getMessage());
        }
        return fileName;
    }
    public String exporterWord(LineEntity lineData, List<EquipmentEntityPage> eqList,String fileName,Map<String,Object> excel) {
        if(null ==lineData || eqList.size()==0){
            return null;
        }
        Integer width = 70;
        Integer width2 = 400;
        String wordName =DateUtil.currentTimestamp().getTime()+"_t.docx";
        // 创建一个新的Word文档
        XWPFDocument doc = new XWPFDocument();
        XWPFParagraph paragraph = doc.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleFun = paragraph.createRun();
        titleFun.setText(lineData.getName());
        titleFun.setBold(true);
        titleFun.setColor("000000");
        titleFun.setFontSize(15);
        if(eqList.size()>0){
            if(!StringUtils.isBlank(fileName)){
                XWPFTable table1 = doc.createTable(2, 0);
                //添加百度图片
                XWPFTableRow row = table1.getRow(0); // 获取行
                XWPFTableCell cell1 = row.getCell(0);
                cell1.setWidth(String.valueOf((width+width2) * 20));
                XWPFRun run = cell1.getParagraphs().get(0).createRun();
                // 图片文件路径
                String imgFile = ADDRESS_FILE+fileName;
                try {
                    File file=new File(imgFile);
                    if(file.exists()){
                        BufferedImage image = ImageIO.read(file);
                        int originalWidth = image.getWidth();
                        int originalHeight = image.getHeight();
                        int newWidth  =350;
                        int newHeight = (newWidth * originalHeight) / originalWidth;
                        FileInputStream fis = new FileInputStream(file);
                        run.addPicture(fis, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(newWidth), Units.toEMU(newHeight));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 设置垂直和水平居中
                for (XWPFParagraph paragraphs : cell1.getParagraphs()) {
                    paragraphs.setVerticalAlignment(TextAlignment.CENTER);
                    paragraphs.setAlignment(ParagraphAlignment.CENTER);
                }
                XWPFTableRow row2 = table1.getRow(1); // 获取行
                XWPFTableCell cell= row2.getCell(0);
                cell.setWidth(String.valueOf((width+width2) * 20));
                CTTc ctTc = cell.getCTTc();
                CTP ctP = (ctTc.sizeOfPArray() == 0) ?ctTc.addNewP() : ctTc.getPArray(0);
                XWPFParagraph par = cell.getParagraph(ctP);
                //设置水平居中
                par.setAlignment(ParagraphAlignment.CENTER);
                //设置垂直居中
                par.setVerticalAlignment(TextAlignment.CENTER);
                XWPFRun runs = par.createRun();
                runs.setFontSize(13);
                runs.setText("路线详情");
            }
            // 创建一个表格
            for (EquipmentEntityPage eq:eqList) {
                //开始动态的列
                Integer rows=10;
                if(eq.getRoughInType().equals("2")){
                    rows = rows+2;
                }
                if(null != eq.getPipeFileImgId()){
                    rows++;
                }
                XWPFTable table = doc.createTable(rows, 2);
                //开始新增对应坐标点数据
                Integer startRows =0;
                int rowsIndex=0;
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"定点名称",eq.getName());
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"经度",eq.getWgLgt());
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"维度",eq.getWgDms());
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"埋深",eq.getDepthNumber());
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"设备情况",eq.getEquipmentName());
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"敷设方式",getRoughInName(eq));
                if(eq.getRoughInType().equals("2")){
                    String h= null == eq.getHolesNumber()?"0":String.valueOf(eq.getHolesNumber());
                    String c= null == eq.getCableNumber()?"0":String.valueOf(eq.getCableNumber());
                    rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"顶管孔数",h);
                    rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"线缆条数",c);
                }
                if(null != eq.getPipeFileImgId()){
                    FileUrlEntity fileUrlEntity =    fileUrlService.selectById(Long.parseLong(eq.getPipeFileImgId()));
                    if(null !=fileUrlEntity){
                        rowsIndex = getRowsIndexFileName(
                                width, width2, table, startRows, rowsIndex,
                                "顶管剖面图",fileUrlEntity.getUrl());
                    }
                }
                /*if(null != excel.get("fileNameByChart")){
                    String strImg = (String) excel.get("fileNameByChart");
                    rowsIndex = getRowsIndexFileName(width, width2, table, startRows, rowsIndex,"顶管剖面图",strImg);
                }*/
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"描述",eq.getNotes());
                rowsIndex = getRowsIndexByImg(width, width2, table, startRows, rowsIndex,"现场图片",eq);
                rowsIndex = getRowsIndex(width, width2, table, startRows, rowsIndex,"图片备注",eq.getNotesImg());
            }
        }
        // 将文档保存到磁盘
        try (FileOutputStream out = new FileOutputStream(ADDRESS_FILE+wordName)) {
            doc.write(out);
        }catch (Exception e){
            log.info(e.getMessage());
            return null;
        }
        return wordName;
    }

    private String getRoughInName(EquipmentEntityPage eq) {
        String roughInName ="直埋";
        Map<String,Object> map =new HashMap<>();
        map.put("dictType","fsfx");
        SysDictTypeDTO sysDictTypeDTO = sysDictTypeService.findOnly(map);
        if(null !=sysDictTypeDTO) {
            //开始获取对应参数字典数据
            map = new HashMap<>();
            map.put("dictTypeId", String.valueOf(sysDictTypeDTO.getId()));
            List<SysDictDataDTO> lists = sysDictDataService.list(map);
            if(CollectionUtil.isNotEmpty(lists)){
                for (SysDictDataDTO dto:lists) {
                    if(eq.getRoughInType().equals(dto.getDictValue())){
                        roughInName =dto.getDictLabel();
                    }
                }
            }
        }
        return roughInName;
    }



    private int getRowsIndex(Integer width, Integer width2, XWPFTable table, Integer startRows, int rowsIndex,String row1Text,String row2Text) {
        XWPFTableRow rowFor = table.getRow(startRows + rowsIndex);
        rowFor.getCell(0).setWidth(String.valueOf(width * 20));
        rowFor.getCell(0).setText(row1Text);
        rowFor.getCell(1).setWidth(String.valueOf(width2 * 20));
        rowFor.getCell(1).setText(row2Text); 
        rowsIndex++;
        return rowsIndex;
    }
    private int getRowsIndexByImg(Integer width, Integer width2, XWPFTable table, Integer startRows, int rowsIndex,String row1Text,EquipmentEntityPage eq) {
        XWPFTableRow rowFor = table.getRow(startRows + rowsIndex);
        rowFor.getCell(0).setWidth(String.valueOf(width * 20));
        rowFor.getCell(0).setText("现场图片");
        rowFor.getCell(1).setWidth(String.valueOf(width2 * 20));
        XWPFTableCell cellImg = rowFor.getCell(1);
        XWPFParagraph pphImg = cellImg.addParagraph();
        //放在同一个run中不会换行
        XWPFRun r= pphImg.createRun();
        if(eq.getList().size()>0){
            for (FileUrlDTO f :eq.getList()) {
                File file = new File(ADDRESS_FILE+f.getUrl());
                if(file.exists()){
                    try {
                        BufferedImage images = ImageIO.read(file);
                        int newWidth =100;
                        int originalWidth = images.getWidth();
                        int originalHeight = images.getHeight();
                        int newHeight = (newWidth * originalHeight) / originalWidth;
                        FileInputStream fisImg = new FileInputStream(file);
                        String imgFile1 = "";
                        r.addPicture(fisImg, XWPFDocument.PICTURE_TYPE_JPEG, imgFile1, Units.toEMU(newWidth), Units.toEMU(newHeight));
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }
        rowsIndex++;
        return rowsIndex;
    }

    private int getRowsIndexFileName(Integer width, Integer width2, XWPFTable table, Integer startRows, int rowsIndex,String row1Text,String fileName) {
        XWPFTableRow rowFor = table.getRow(startRows + rowsIndex);
        rowFor.getCell(0).setWidth(String.valueOf(width * 20));
        rowFor.getCell(0).setText(row1Text);
        rowFor.getCell(1).setWidth(String.valueOf(width2 * 20));
        XWPFTableCell cellImg = rowFor.getCell(1);
        XWPFParagraph pphImg = cellImg.addParagraph();
        //放在同一个run中不会换行
        XWPFRun r= pphImg.createRun();
        // 图片文件路径
        String imgFile = ADDRESS_FILE+fileName;
        try {
            File file=new File(imgFile);
            if(file.exists()){
                BufferedImage image = ImageIO.read(file);
                int originalWidth = image.getWidth();
                int originalHeight = image.getHeight();
                int newWidth  =200;
                int newHeight = (newWidth * originalHeight) / originalWidth;
                FileInputStream fis = new FileInputStream(file);
                r.addPicture(fis, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(newWidth), Units.toEMU(newHeight));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 设置垂直和水平居中
        for (XWPFParagraph paragraphs : cellImg.getParagraphs()) {
            paragraphs.setVerticalAlignment(TextAlignment.CENTER);
            paragraphs.setAlignment(ParagraphAlignment.CENTER);
        }
        rowsIndex++;
        return rowsIndex;
    }

    public String getBaiduImgFileName(List<EquipmentEntityPage> eqList) {
        return null;
    }


    public static long generateRandomLongId() {
        return ThreadLocalRandom.current().nextLong();
    }

    public static Integer getMiddleElement(List<?> list) {
        int size = list.size();
        if (size % 2 == 1) {
            // List大小是奇数，正中间的数据
            return (size - 1) / 2;
        } else {
            // List大小是偶数，取中间两个元素的任一个
            return (size / 2) - 1;
        }
    }
}